type ICallback = (arg: unknown) => unknown;
type ICallbacks = ICallback[];

interface IEvents {
  [key: string]: ICallbacks;
}

function createEmitter() {
  // Store custom event content
  const events: IEvents = {};

  return {
    // Bind custom event
    on(eventName: string, callback: ICallback) {
      if (typeof callback !== 'function') {
        console.error("Callback must be a function.");
        return;
      }

      if (!events[eventName]) {
        events[eventName] = [];
      }

      events[eventName].push(callback);
      console.log("Current events:", JSON.stringify(events));
    },

    // Unbind custom event
    off(eventName: string, callback?: ICallback) {
      const callbacks = events[eventName];
      if (!callbacks) {
        return;
      }

      if (callback) {
        // Remove specific callback
        events[eventName] = callbacks.filter(cb => cb !== callback);
      } else {
        // Remove all callbacks for the event
        delete events[eventName];
      }
    },

    // Trigger custom event
    emit(eventName: string, arg?: unknown) {
      const callbacks = events[eventName];
      if (!callbacks) {
        console.warn(`No callbacks found for event: ${eventName}`);
        return; // No callbacks to execute
      }

      callbacks.forEach(cb => cb(arg));
    },
  };
}

const globalEmitter = createEmitter();

export default globalEmitter;
